package com.bwie.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.mapper.TbOrderDetailMapper;
import com.bwie.mapper.TbOrderRecordMapper;
import com.bwie.mapper.TbProdInfoMapper;
import com.bwie.poi.ExcelUtil;
import com.bwie.pojo.*;
import com.bwie.service.IUserService;
import com.bwie.service.TbOrderService;
import com.bwie.mapper.TbOrderMapper;
import com.bwie.utils.R;
import com.bwie.utils.TokenUtils;

import com.bwie.vo.OrderDetailVo;
import com.bwie.vo.PageInfoVo;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @author Lenovo
* @description 针对表【tb_order(订单表)】的数据库操作Service实现
* @createDate 2025-06-20 15:28:36
*/
@Service
public class TbOrderServiceImpl extends ServiceImpl<TbOrderMapper, TbOrder>
    implements TbOrderService{

    @Autowired
    TbOrderMapper tbOrderMapper;
    @Autowired
    TbProdInfoMapper tbProdInfoMapper;
    @Autowired
    HttpServletRequest request;
    @Autowired
    TbOrderDetailMapper tbOrderDetailMapper;
    @Autowired
    TbOrderRecordMapper tbOrderRecordMapper;
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    HttpServletResponse response;
    @Autowired
    IUserService iUserService;

    @Override
    public R getOrderList(PageInfoVo pageInfoVo) {
        Page<TbOrder> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());

        LambdaQueryWrapper<TbOrder> wrapper = new LambdaQueryWrapper<>();

        if(StringUtils.isNotEmpty(pageInfoVo.getKeyWord())){
            wrapper.like(TbOrder::getProdInfo,pageInfoVo.getKeyWord())
                    .or()
                    .eq(TbOrder::getOrderId,pageInfoVo.getKeyWord());
        }
        if(pageInfoVo.getStatusId()!=null){
            wrapper.eq(TbOrder::getOrderStatus,pageInfoVo.getStatusId());
        }
        if(pageInfoVo.getTypeId()!=null){
            wrapper.eq(TbOrder::getOrderType,pageInfoVo.getTypeId());
        }

        wrapper.orderByDesc(TbOrder::getOrderId);

        Page<TbOrder> tbOrderPage = tbOrderMapper.selectPage(page, wrapper);

        for (TbOrder record : tbOrderPage.getRecords()) {
            List<String> imagesList = tbOrderMapper.getOrderImageList(record.getOrderId());
            ArrayList<String> imageList = new ArrayList<>();
            if(imagesList != null && imagesList.size()>0){
                for (String s : imageList) {
                    if(s!=null){
                        List<String> list = JSON.parseArray(s, String.class);
                        imageList.addAll(list);
                    }
                }
            }
            record.setImageList(imageList);
        }

        /*
            for (TbOrder record : tbOrderPage.getRecords()) {
                List<String> imagesList = tbOrderMapper.getOrderImageList(record.getOrderId());
                ArrayList<String> imageList = new ArrayList<>();
                if(imagesList!=null && imagesList.size()>0){
                    for (String s : imagesList) {
                        if(s!=null){
                            List<String> list = JSON.parseArray(s, String.class);
                            imageList.addAll(list);
                        }
                    }
                }
                record.setImageList(imageList);
            }
         */

        //数据返回之前，把前端显示的列表，存入缓存
        String token = request.getHeader("token");
        if(token == null){
            return R.error(404,"请先登录");
        }
        Integer userId = TokenUtils.getUserId(token);
        String key = "order-list"+userId;
        stringRedisTemplate.opsForValue().set(key,JSON.toJSONString(tbOrderPage.getRecords()));

        return R.ok(tbOrderPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R addOrder(List<TbProdInfo> infoList) {

        String token = request.getHeader("token");
        if(token == null){
            return R.error(404,"请先登录");
        }
        Integer userId = TokenUtils.getUserId(token);
        String userName = TokenUtils.getUserName(token);

        //检查库存
        BigDecimal totalAmount = new BigDecimal("0.0");
        StringBuilder prodNames = new StringBuilder();

        RLock lock = redissonClient.getLock("order-lock");

        try {
            //加锁
            lock.lock();

            for (TbProdInfo tbProdInfo : infoList) {
                TbProdInfo prodInfo = tbProdInfoMapper.selectById(tbProdInfo.getInfoId());
                if(tbProdInfo.getBuyNum() > prodInfo.getProdStock()){
                    throw new RuntimeException("商品库存不足");
                }

                //减少并更新库存
                tbProdInfo.setProdStock(prodInfo.getProdStock() - tbProdInfo.getBuyNum());
                tbProdInfoMapper.updateById(tbProdInfo);

                //计算订单金额
                totalAmount = totalAmount.add(tbProdInfo.getProdPrice().multiply(new BigDecimal(tbProdInfo.getBuyNum())));

                //拼接名字
                if(prodNames.length()>0){
                    prodNames.append(",");
                    prodNames.append(tbProdInfo.getProdName());
                }else{
                    prodNames.append(tbProdInfo.getProdName());
                }
            }

        } finally {
            //解锁
            lock.unlock();
        }

        //创建订单
        TbOrder tbOrder = new TbOrder();
        //雪花算法生成订单ID
        long id = IdUtil.getSnowflake(1, 1).nextId();
        tbOrder.setOrderNo(""+id);
        tbOrder.setOrderAmount(totalAmount);
        tbOrder.setOrderStatus(0);
        tbOrder.setOrderType(1);
        tbOrder.setProdInfo(prodNames.toString());
        tbOrder.setCreateBy(userName);
        tbOrder.setCreateTime(new Date());
        tbOrder.setUserId(userId);
        tbOrderMapper.insert(tbOrder);

        //创建订单明细
        for (TbProdInfo tbProdInfo : infoList) {
            TbOrderDetail tbOrderDetail = new TbOrderDetail();
            //关联订单
            tbOrderDetail.setOrderId(tbOrder.getOrderId());
            tbOrderDetail.setInfoId(tbProdInfo.getInfoId());
            tbOrderDetail.setProdId(tbProdInfo.getProdId());
            tbOrderDetail.setBuyNum(tbProdInfo.getBuyNum());
            tbOrderDetail.setBuyPrice(tbProdInfo.getProdPrice());
            tbOrderDetail.setCreateBy(userName);
            tbOrderDetail.setCreateTime(new Date());
            tbOrderDetailMapper.insert(tbOrderDetail);
        }


        //添加订单记录
        TbOrderRecord tbOrderRecord = new TbOrderRecord();
        tbOrderRecord.setOrderId(tbOrder.getOrderId());
        tbOrderRecord.setOptRecord("用户创建订单");
        tbOrderRecord.setCreateBy(userName);
        tbOrderRecord.setCreateTime(new Date());
        tbOrderRecordMapper.insert(tbOrderRecord);

        return R.ok();
        /*
            String token = request.getHeader("token");
            if(token == null){
                return R.error(500,"请先登录");
            }
            Integer userId = TokenUtils.getUserId(token);
            String userName = TokenUtils.getUserName(token);

            //检查库存
            BigDecimal totalAmount = new BigDecimal("0.0");
            StringBuilder prodNames = new StringBuilder();

            RLock lock = redissonClient.getLock("order-lock");
            try {
                //加锁
                lock.lock();

                for (TbProdInfo tbProdInfo : infoList) {
                    TbProdInfo prodInfo = tbProdInfoMapper.selectById(tbProdInfo.getInfoId());
                    if(tbProdInfo.getBuyNum() > prodInfo.getProdStock()){
                        throw new RuntimeException("商品库存不足");
                    }

                    //扣减并更新库存
                    prodInfo.setProdStock(prodInfo.getProdStock() - tbProdInfo.getBuyNum());
                    tbProdInfoMapper.updateById(prodInfo);

                    //计算订单金额
                    totalAmount = totalAmount.add(tbProdInfo.getProdPrice().multiply(new BigDecimal(tbProdInfo.getBuyNum())));

                    //拼接商品名称
                    if(prodNames.length()>0){
                        prodNames.append(",");
                        prodNames.append(tbProdInfo.getProdName());
                    }else{
                        prodNames.append(tbProdInfo.getProdName());
                    }
                }

            } finally {
                //解锁
                lock.unlock();
            }

            //创建订单
            TbOrder tbOrder = new TbOrder();
            //雪花算饭生成订单编号
            long id = IdUtil.getSnowflake(1, 1).nextId();
            tbOrder.setOrderNo(id+"");

            tbOrder.setOrderType(1);
            tbOrder.setOrderStatus(0);
            tbOrder.setUserId(userId);
            tbOrder.setOrderAmount(totalAmount);
            tbOrder.setProdInfo(prodNames.toString());
            tbOrder.setCreateTime(new Date());
            tbOrderMapper.insert(tbOrder);

            //创建订单明细
            for (TbProdInfo tbProdInfo : infoList) {
                TbOrderDetail tbOrderDetail = new TbOrderDetail();
                //关联订单
                tbOrderDetail.setOrderId(tbOrder.getOrderId());
                tbOrderDetail.setBuyNum(tbProdInfo.getBuyNum());
                tbOrderDetail.setProdId(tbProdInfo.getProdId());
                tbOrderDetail.setBuyPrice(tbProdInfo.getProdPrice());
                tbOrderDetail.setInfoId(tbProdInfo.getInfoId());
                tbOrderDetail.setCreateBy(userName);
                tbOrderDetail.setCreateTime(new Date());

                tbOrderDetailMapper.insert(tbOrderDetail);
            }

            //新增订单记录
            TbOrderRecord tbOrderRecord = new TbOrderRecord();
            tbOrderRecord.setOrderId(tbOrder.getOrderId());
            tbOrderRecord.setOptRecord("用户订单创建");
            tbOrderRecord.setCreateBy(userName);
            tbOrderRecord.setCreateTime(new Date());
            tbOrderRecordMapper.insert(tbOrderRecord);

            return R.ok();
         */
    }

    @Override
    public void exportOrderList(Integer userId){
        ExcelUtil<TbOrder> excelUtil = new ExcelUtil<>(TbOrder.class);

        List<TbOrder> tbOrderList = tbOrderMapper.selectList(
                new LambdaQueryWrapper<TbOrder>().eq(TbOrder::getUserId, userId)
        );

        excelUtil.exportExcel(response,tbOrderList,"订单列表");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R deleteBatchOrder(List<Integer> ids) {
        if(ids==null||ids.size()<=0){
            return R.error(404,"请选择要删除的数据");
        }
        //删除订单
        tbOrderMapper.deleteBatchIds(ids);
        //删除订单明细表
        tbOrderDetailMapper.delete(
                new LambdaQueryWrapper<TbOrderDetail>().in(TbOrderDetail::getOrderId,ids)
        );
        return R.ok();
    }

    @Override
    public R getOrderInfoById(Integer orderId) {
        TbOrder tbOrder = tbOrderMapper.selectById(orderId);
        if(tbOrder == null){
            return R.error(404,"订单不存在");
        }

        //获取用户信息
        R r = iUserService.getUserInfoById(tbOrder.getUserId());
        if(r.getCode() != 200){
            return r;
        }
        String s = JSON.toJSONString(r.getData());
        TbUser tbUser = JSON.parseObject(s, TbUser.class);
        tbOrder.setUser(tbUser);

        //获取商品明细信息
        List<OrderDetailVo> orderDetailList = tbOrderMapper.getOrderDetailList(orderId);
        tbOrder.setDetailList(orderDetailList);

        //获取订单记录信息
        List<TbOrderRecord> recordList = tbOrderMapper.getOrderRecordList(orderId);
        tbOrder.setRecordList(recordList);

        return R.ok(tbOrder);
    }

}




